package com.shareyi.springcore.beanlife;

import com.shareyi.springcore.bean.HelloBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Service;

/**
 * Created by david on 2017/5/14.
 */
@Service
public class MyBeanPostProcessor implements BeanPostProcessor {


    /**
     * 在bean实例化之后，参数已经被注入，即property设置的值可以直接取到
     *  但是还没有调用bean的：afterPropertiesSet 方法
     *
     *  在这儿你能干什么？
     *   1. 修改已经设置的值，比如之前设置值为张三，这里可以改为李四；
     *   2. 注意到这个方法会返回对象，其实在这里如果返回一个新对象会替换掉原来的对象。（要和原来的bean的类型一致，不然可能会报错），也就是你可以生成一个包装类，或者代理类；
     *   3. 扫描你的bean，并对bean的特殊注解进行处理；
     *
     *
     *  postProcessAfterInitialization 相关功能同上，只是各自调用顺序有差别。
     *
     *
     * @param o
     * @param beanName
     * @return
     * @throws BeansException
     */
    public Object postProcessBeforeInitialization(Object o, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization 我被调用了");
        if(o instanceof HelloBean){
            HelloBean helloBean= (HelloBean) o;
            System.out.println("hello bean  原始设置值:"+helloBean);
            helloBean.setName("我的名字被修改了");
            System.out.println("hello bean name 原始设置值已经被修改");


            /***
             * 替换bean的功能被注释了，测试结果是确实被替换了
             */
          /*  HelloBean newBean=new HelloBean();
            newBean.setName("我是一个替换bean");
            return newBean;*/

            /**
             * 替换bean 可以换一个类型完全不一样的对象么？
             *  会不会报错， 测试了，如果这个bean没有被其他地方依赖，是不会报错的
             *  如果这个bean被其他地方依赖了，Injection of resource dependencies failed;  会报错
             */
          /*  Object newBean=new Object();
            return newBean;*/

        }
        return o;
    }


    /**
     * 在bean实例化之后，参数已经被注入，即property设置的值可以直接取到
     *  已经调用bean的：afterPropertiesSet 方法
     * @param o
     * @param beanName
     * @return
     * @throws BeansException
     */
    public Object postProcessAfterInitialization(Object o, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization 我被调用了");
        if(o instanceof HelloBean){
            HelloBean helloBean= (HelloBean) o;
            System.out.println("hello bean name:"+helloBean.getName());
        }
        return o;
    }
}
